import { ZipReader, BlobReader, BlobWriter, type FileEntry, getMimeType } from '@zip.js/zip.js'
import { blobToBase64 } from '@/utils/format'
import { NInput, type DialogApi, type MessageApi } from 'naive-ui';
import { h, ref } from 'vue';
import { db } from '@/db/db';

const password = ref('')

function getCover(entry: FileEntry, password?: string): Promise<string> {
  return new Promise(async (resolve, reject) => {
    try {
      let res: Blob
      if (password) {
        res = await entry.getData(new BlobWriter(getMimeType(entry.filename)), { password: password })
      } else {
        res = await entry.getData(new BlobWriter(getMimeType(entry.filename)))
      }
      const base64 = await blobToBase64(res)

      resolve(base64)
    } catch (err) {
      console.log("🚀 ~ getCover ~ err:", err)
      reject(err)
    }
  })
}

export type zipCoverType = { img: string; password?: string }

export default (data: File, name: string, dialog: DialogApi, message: MessageApi): Promise<zipCoverType> => {
  return new Promise(async (resolve, reject) => {
    const zipFileReader = new BlobReader(data)
    const zipReader = new ZipReader<FileEntry>(zipFileReader)
    const entry = (await zipReader.getEntries()).find(i => !i.directory) as FileEntry

    if (!entry) reject('文件内容有误')

    if (entry.encrypted) {
      // 先查询是否有满足的密码
      const passwords = (await db.books.filter((book) => Boolean(book.password)).toArray()).map(i => i.password) as string[]
      if (passwords.length) {
        const pwd = await verifyPassword(passwords, entry)
        if (pwd) {
          const res = await getCover(entry, pwd)
          resolve({ img: res, password: password.value })
          return
        }
      }

      const d = dialog.warning({
        maskClosable: false,
        closable: false,
        title: `【${name}】 需要密码`,
        content: () => inputPasswordComponent(),
        positiveText: '确认',
        onPositiveClick: () => {
          if (!password.value) {
            message.error('密码不能为空')
            return false
          }
          d.loading = true
          return new Promise((dialogResolve) => {
            getCover(entry, password.value).then(res => {
              resolve({ img: res, password: password.value })
              password.value = ''
              dialogResolve(true)
            }).catch(() => {
              message.error('密码不正确')
              d.loading = false
              dialogResolve(false)
            })
          })
        }
      })

    } else {
      getCover(entry).then(res => resolve({ img: res })).catch(() => reject('解析有误'))
    }
  })
}

function inputPasswordComponent() {
  return h('div', {}, [
    h('p', {}, '密码输入后会保存在本地；文件资源越大解析所需时间越长，请不要关闭窗口耐心等待'),
    h(NInput, {
      onUpdateValue: (newVal) => password.value = newVal,
      placeholder: '请输入此压缩包的密码'
    })
  ])
}

function verifyPassword(passwords: string[], entry: FileEntry): Promise<string | ''> {
  return new Promise((resolve, reject) => {

    const promises = passwords.map(i => {
      return entry.getData(new BlobWriter(getMimeType(entry.filename)), { password: i })
    })
    Promise.all(promises).then(values => {
      const index = values.findIndex(i => Boolean(i))
      if (index !== -1) resolve(passwords[index])
      else reject('')
    })
  })
}
